package com.sanctity.config;

import com.sanctity.constant.RabbitConstants;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;

/***
 * @belongsProject spring-cloud
 * @description <TODO description class purpose>
 * @author Sanct
 * @version 1.0.0
 * @create 2024/1/25 11:42
 **/
@Configuration
public class RabbitMQConfig {

    /**
     * 创建医生工作站消息队列连接工厂
     * @param host
     * @param port
     * @param username
     * @param password
     * @return
     */
    @Bean(name = "docConFactory")
    @Primary
    public ConnectionFactory docConFactory(
           @Value("${spring.rabbitmq.cloud_doctor.host}")  String host,
           @Value("${spring.rabbitmq.cloud_doctor.port}")  String port,
           @Value("${spring.rabbitmq.cloud_doctor.username}")  String username,
           @Value("${spring.rabbitmq.cloud_doctor.password}")  String password,
           @Value("${spring.rabbitmq.cloud_doctor.virtual-host}") String virtualHost
    ){
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
        cachingConnectionFactory.setAddresses(host+":"+port);
        cachingConnectionFactory.setUsername(username);
        cachingConnectionFactory.setPassword(password);
        cachingConnectionFactory.setVirtualHost(virtualHost);
        // 开启交换机应答模式
        cachingConnectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
        // 开启回退模式即队列应答
        cachingConnectionFactory.setPublisherReturns(true);
        return cachingConnectionFactory;
    }

    /**
     * 注册通过指定的连接工厂实例化RabbitMQ模板
     * @param connectionFactory
     * @return
     */
    @Bean(name = "docRabbitTemplate")
    @Primary
    @Scope("prototype")
    public RabbitTemplate docRabbitTemplate(
          @Qualifier("docConFactory") ConnectionFactory connectionFactory
    ){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.setMandatory(true);
//        rabbitTemplate.setConfirmCallback();
        return rabbitTemplate;
    }

    @Bean("docFactory")
    public SimpleRabbitListenerContainerFactory docFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            @Qualifier("docConFactory") ConnectionFactory connectionFactory
    ){
        SimpleRabbitListenerContainerFactory containerFactory = new SimpleRabbitListenerContainerFactory();
        containerFactory.setConcurrentConsumers(10);
        containerFactory.setMaxConcurrentConsumers(20);
        containerFactory.setPrefetchCount(1);
        configurer.configure(containerFactory,connectionFactory);
        containerFactory.setMessageConverter(new Jackson2JsonMessageConverter());
        return containerFactory;
    }

    /**
     * 注册工厂消息转换
     * @return
     */
    @Bean("docFactory")
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    @Bean("docOrderStuQue")
    public Queue messageQueue(){
        return new Queue(RabbitConstants.MESSAGE_QUEUE,true);
    }

    @Bean("docOrderStuExchg")
    public DirectExchange directExchange(){
//        return ExchangeBuilder.directExchange(RabbitConstants.DIRECT_EXCHANGE).build();
        return new DirectExchange(RabbitConstants.DIRECT_EXCHANGE);
    }

    @Bean
    public Binding directBindMessage(
            @Qualifier("docOrderStuQue") Queue queue,
            @Qualifier("docOrderStuExchg") Exchange exchange
    ){
        return BindingBuilder.bind(queue).to(exchange).with(RabbitConstants.MESSAGE_ROUTING_KEY).noargs();
    }
}
